package com.chuanke.ckfamily.service.user.impl;

import com.chuanke.ckfamily.dao.social.model.Family;
import com.chuanke.ckfamily.dao.social.model.SpecialRelation;
import com.chuanke.ckfamily.dao.user.FriendApplyDao;
import com.chuanke.ckfamily.dao.user.model.FriendApply;
import com.chuanke.ckfamily.dao.user.model.FriendApplyRecord;
import com.chuanke.ckfamily.dao.user.model.User;
import com.chuanke.ckfamily.dao.user.model.UserRelation;
import com.chuanke.ckfamily.service.base.FailCode;
import com.chuanke.ckfamily.service.common.CacheService;
import com.chuanke.ckfamily.service.common.WyService;
import com.chuanke.ckfamily.service.common.impl.RedisLockUtil;
import com.chuanke.ckfamily.service.constant.FriendApplyType;
import com.chuanke.ckfamily.service.constant.SpecialRelationConstant;
import com.chuanke.ckfamily.service.constant.UserRelationType;
import com.chuanke.ckfamily.service.exception.CFException;
import com.chuanke.ckfamily.service.social.FamilyService;
import com.chuanke.ckfamily.service.social.SpecialRelationService;
import com.chuanke.ckfamily.service.user.FriendApplyService;
import com.chuanke.ckfamily.service.user.UserRelationService;
import com.chuanke.ckfamily.service.user.UserService;
import com.weijie.core.BaseBiz;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class FriendApplyServiceImpl extends BaseBiz<FriendApply, FriendApplyDao> implements FriendApplyService {

	private static final Logger log = LoggerFactory.getLogger(FriendApplyServiceImpl.class);
	@Autowired
	private UserService userService;

	@Autowired
	private UserRelationService userRelationService;

	@Autowired
	private CacheService cacheService;

	@Autowired
	private SpecialRelationService specialRelationService;

	@Autowired
	private WyService wyService;

	@Autowired
	private FamilyService familyService;

	@Override
	public String getApplyHi(Long request, String targerNo) {
		try {
			User user = userService.findById(request);
			User tagerUser = userService.findByUserNo(targerNo);

			Family targetFamily = familyService.findFamilyByUserId(tagerUser.getId());
			Family reqeustFamiliy = familyService.findFamilyByUserId(request);
			if (reqeustFamiliy != null && targetFamily != null && targetFamily.getId() != reqeustFamiliy.getId().longValue()) {
				return "我是" + user.getNick_name();

			} else {
				StringBuilder buiderName = new StringBuilder("我是");
				if (reqeustFamiliy != null) {
					buiderName.append(reqeustFamiliy.getName()).append("家族的");
				}
				buiderName.append(user.getNick_name());
				return buiderName.toString();

			}

		} catch (Exception e) {
			return "我是" + request;

		}
	}

	@Override
	public void deleteApply(Long requester, Long responser) throws CFException {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("requester", requester);
		param.put("responser", responser);
		baseDao.deleteFriendApply(param);
	}

	@Override
	public void applyFriend(Long requester, String userNo, String hi, String remark) throws CFException {
		User requesterUser = userService.findById(requester);
		User responserUser = userService.findByUserNo(userNo);
		Long responser = userService.findByUserNo(userNo).getId();
		if (requesterUser == null || responserUser == null || requesterUser.equals(responserUser)) {
			throw new CFException(FailCode.USER_NOT_EXIST);
		}

		if (userService.checkIsFans(requester, responser)) {
			throw new CFException(FailCode.APP, "此用户是你的粉丝");
		}

		log.debug("applay freign ======== request={}, response={}", requester, userNo);
		if (canApply(requester, responser)) {
			FriendApply friendApply1 = getFriendApply(requester, responser);
			if (friendApply1 == null) {
				log.debug("---------------> 创建申请记录");
				addFriendApply(requester, responser, FriendApplyType.APPLY.getType(), hi, remark);
				boolean black = specialRelationService.isBlack(responserUser.getId(),requesterUser.getId());
				if(!black && requesterUser.hasWyId() && responserUser.hasWyId()){
					wyService.sendVideoMsgForUser(requesterUser, responserUser);
				}

			} else {
				log.debug("---------------> 更新申请记录");
				updateFriendApply(friendApply1, null, hi, remark);

			}
			unblack(requesterUser.getId(), responserUser.getId());
			
		}

		if (canCreateRelation(requester, responser)) {
			FriendApply friendApply1 = getFriendApply(requester, responser);
			updateFriendApply(friendApply1, FriendApplyType.AGREE.getType(), null, remark);
			FriendApply friendApply2 = getFriendApply(responser, requester);
			updateFriendApply(friendApply2, FriendApplyType.AGREE.getType(), null, remark);
			userRelationService.deleteBlackWy(requesterUser.getId(), responserUser.getId());
			userRelationService.addUserRelation(requester, responser, friendApply1.getFriend_remark());
			userRelationService.addUserRelation(responser, requester, friendApply2.getFriend_remark());
			createFriendRelationForWy(requesterUser.getId(), responserUser.getId());
		}
	}

	private void unblack(Long uid, Long tuserId) throws CFException {
//		User user = userService.findById(uid);
//		User tuser = userService.findById(tuserId);
		
		SpecialRelation relation = specialRelationService.findSpecialRelation(uid, tuserId, SpecialRelationConstant.relation_type_black);
		if (relation != null) {
			specialRelationService.delete(relation);
			
			specialRelationService.black(uid, tuserId,  SpecialRelationConstant.relation_value_unBlackMute);
//			wyService.setSpecialRelation(user.getUser_no(), tuser.getUser_no(), SpecialRelationConstant.relation_type_black, SpecialRelationConstant.relation_value_unBlackMute);
		}
		
	}

	private boolean canApply(Long requester, Long responser) throws CFException {
		UserRelation userRelation = userRelationService.getUserRelation(requester, responser);
		if (userRelation != null && userRelation.getType() == UserRelationType.FRIEND.getType()) {
			return false;
		}
		return true;
	}

	private boolean canCreateRelation(Long requester, Long responser) throws CFException {
		FriendApply friendApply1 = getFriendApply(requester, responser);
		FriendApply friendApply2 = getFriendApply(responser, requester);
		return (friendApply1 != null && friendApply1.getType() == FriendApplyType.APPLY.getType())
				&& (friendApply2 != null && friendApply2.getType() == FriendApplyType.APPLY.getType());
	}

	@Override
	public List<FriendApplyRecord> getFriendApplyRecord(Long uid) throws CFException {
		if (userService.findById(uid) == null || userService.findById(uid) == null) {
			throw new CFException(FailCode.USER_NOT_EXIST);
		}
		return baseDao.getFriendApplyRecord(uid);

	}

	@Override
	public void auditApply(Long uid, Long aid, int op) throws CFException {
		if (userService.findById(uid) == null) {
			throw new CFException(FailCode.USER_NOT_EXIST);
		}
		RedisLockUtil lockUtil = null;
		try {
			lockUtil = cacheService.getLock(CacheService.KEY_PREFIX.friend_audit_apply_.name() + uid + "_" + aid);
			FriendApply friendApply = baseDao.findById(aid);
			if (friendApply != null && uid.equals(friendApply.getResponser())) {
				if (FriendApplyType.DELETE.getType() == op) {
					baseDao.delete(friendApply);
				}
				long tuserId=friendApply.getRequester();
				
				if (FriendApplyType.AGREE.getType() == op) {
					if (friendApply.getType() == FriendApplyType.AGREE.getType()) {
						return;
					}
					unblack(uid, tuserId);
					updateFriendApply(friendApply, FriendApplyType.AGREE.getType(), null, null);
					userRelationService.deleteBlackWy(uid, tuserId);
					userRelationService.addUserRelation(uid, tuserId, null);
					userRelationService.addUserRelation(tuserId, uid, friendApply.getFriend_remark());
					createFriendRelationForWy(uid, tuserId);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			
		} finally {
			if (lockUtil != null) {
				lockUtil.unlock();
			}
		}
	}

	/**
	 * 更新用户建立好友时 拉黑关系
	 *
	 * @param uid
	 * @param tid
	 * @throws CFException
	 */
	private void createFriendRelationForWy(Long uid, Long tid) throws CFException {
		log.debug("更新用户建立好友时 拉黑关系 开始=======>uid={},tid={}", uid, tid);
		
		userRelationService.createBlackWy(uid, tid);	
		
		User user = userService.findById(uid);
		
		User tuser = userService.findById(tid);
		
		// 操作拉黑关系后，发送hello
		FriendApply friendApply1 = getFriendApply(uid, tid);
		FriendApply friendApply2 = getFriendApply(tid, uid);

		wyService.sayHello(user, tuser, friendApply2 != null && friendApply2.getType() == FriendApplyType.AGREE.getType() ? friendApply2.getHi() : "");
		wyService.sayHello(tuser, user, friendApply1 != null && friendApply1.getType() == FriendApplyType.AGREE.getType() ? friendApply1.getHi() : "");

		wyService.sendUpdateFriend(user.getUser_no());
		wyService.sendUpdateFriend(tuser.getUser_no());
		log.debug("更新用户建立好友时 拉黑关系 结束=======>uid={},tid={}", uid, tid);
	}

	/**
	 * 保存好友申请记录
	 * 
	 * @param requester
	 * @param responser
	 * @param type
	 */
	private void addFriendApply(Long requester, Long responser, int type, String hi, String remark) {
		FriendApply friendApply = new FriendApply();
		friendApply.setRequester(requester);
		friendApply.setResponser(responser);
		friendApply.setHi(hi);
		friendApply.setFriend_remark(remark);
		friendApply.setType(type);
		friendApply.setCreate_time(new Timestamp(System.currentTimeMillis()));
		baseDao.add(friendApply);
	}

	/**
	 * 更新好友申请记录
	 * 
	 * @param friendApply
	 * @param type
	 */
	private void updateFriendApply(FriendApply friendApply, Integer type, String hi, String remark) {
		FriendApply temp = new FriendApply();
		temp.setId(friendApply.getId());
		temp.setType(type);
		temp.setHi(hi);
		temp.setFriend_remark(remark);
		temp.setUpdate_time(new Timestamp(System.currentTimeMillis()));
		baseDao.update(temp);
	}

	@Override
	public FriendApply getFriendApply(Long requester, Long responser) {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("requester", requester);
		param.put("responser", responser);

		return baseDao.getFriendApply(param);
	}
}